/*
    <one line to give the library's name and an idea of what it does.>
    Copyright (C) 2013  Guillaume <email>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/


#ifndef MSVISUALIZERATOMS_H
#define MSVISUALIZERATOMS_H

#include <msVisualizerSystem.h>
#include <msAtom.h>
#include <ms3dStructure.h>
#include <msKineticOperator.h>

#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRendererCollection.h>
#include <vtkCamera.h>
#include <vtkActor.h>
#include <vtkActor2DCollection.h>
#include <vtkRenderer.h>
#include <vtkInteractorStyleTrackballCamera.h>

#include <vtkPolyData.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkDoubleArray.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkLineSource.h>

#include <vtkCell.h>
#include <vtkCellData.h>
#include <vtkDataSet.h>
#include <vtkDataSetAttributes.h>
#include <vtkProperty.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataAlgorithm.h>

#include <vtkWindowToImageFilter.h>
#include <vtkPNGWriter.h>
#include <vtkJPEGWriter.h>

#include <vtkTubeFilter.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <vtkSphereSource.h>

#include <vtkCommand.h>


namespace atomism
{
  
class msVisualizerAtoms : public msVisualizerSystem
{
  
private:
      //!\name from msRegister 
      //@{
      static msRegistrar Registrar;
      static bool        isVisualizerAtomsRegisteredInPython;
      static msRegister* createInstance() { return new msVisualizerAtoms; }
      //@}   
      
protected:
     
      void registryInPython();
      
      msVisualizerAtoms() : msVisualizerSystem() { constructVar("msVisualizerSystem","VisualizerSystem","system visualizer");
						   Resolution=6; }
      
      void initialize()  {
	   msVisualizerSystem::initialize(); 
           };
	     
      void update(){ msVisualizerSystem::update();  }
      
public:
  
      static boost::shared_ptr<msVisualizerAtoms> New()
          {
	   boost::shared_ptr<msVisualizerAtoms> T( new msVisualizerAtoms );
	   LOGGER_ENTER_FUNCTION_DBG("msVisualizerAtoms::New(boost::shared_ptr<msUnitsManager> units)",T->getFullId());
	   T->initialize(); T->update();
	   LOGGER_EXIT_FUNCTION();
	   return T;
	   }
	
       virtual void watch(boost::shared_ptr<msSystem> system);
       
       void setResolution(int r);
       
       void addToRenderer( boost::shared_ptr<msSystem> system , vtkRenderer* Renderer );
private:
  
      boost::shared_ptr<ms3dStructure> Objects;
      
      int Resolution;
      
      int isBondedByCovalent(msAtom* a1,msAtom* a2);
      void createAtoms(boost::shared_ptr<msSystem> system);
      void createBonds(boost::shared_ptr<msSystem> system);
  
};


class msDynamicManager : public vtkCommand , public msTreeMapper
{ 

private:
      //!\name from msRegister 
      //@{
      static msRegistrar Registrar;
      static bool        isDynamicManagerRegisteredInPython;
      static msRegister* createInstance() { return new msDynamicManager; }
      //@}
   
protected:
      void registryInPython();
      
      msDynamicManager() : vtkCommand() , msTreeMapper() { vtkStyleInteract=0; TimerCount=0; dt=50;}
      
      void initialize()  { msTreeMapper::initialize(); 
                           msTreeMapper::declareAttribute(dt,"dt");
                           };
	     
      void update(){ msTreeMapper::update();  }

public:
      
      static boost::shared_ptr<msDynamicManager> New()
          {
	   boost::shared_ptr<msDynamicManager> T( new msDynamicManager );
	   T->initialize();T->update();
	   return T;
	   }      

     
      void watch(  boost::shared_ptr<msVisualizerAtoms> viewer, boost::shared_ptr<msKineticOperator> kinop , size_t i)
              {  
               vtkStyleInteract=0; 
	       TimerCount=0;
	       KineticOperator = kinop; 
	       qi = KineticOperator->getCoordinates()->operator[](i);
	       indice =i;
	       Visualizer=viewer;
	       KineticOperator->move(i);
               launch();
	       };

     boost::shared_ptr<msTreeMapper> set_dt(int i){ if(i>0) dt=i; return mySharedPtr();}

private:

      void launch();

      int dt; //in ms

      msVector3dContainer Coors0;

      msVector3dContainer Coors1;

      vtkSmartPointer<vtkRenderer> renderer;

      boost::shared_ptr<msVisualizerAtoms> Visualizer;

      boost::shared_ptr<msKineticOperator> KineticOperator; 

      boost::shared_ptr<msScalarVariable> qi; size_t indice;

      void clearRendered(vtkRenderer* Renderer);

      int TimerCount;
      vtkActor* actor;
      vtkInteractorStyleTrackballCamera *vtkStyleInteract;
      
      void Execute( vtkObject *caller, unsigned long eventId,
                    void * vtkNotUsed(callData) );
      };  



}
#endif // MSVISUALIZERATOMS_H
